package com.apes.fn.server.servicePlan.service;


import afu.org.checkerframework.checker.units.qual.A;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.business.fixedLoss.modle.LossQuotation;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.scm.commodityInquiry.model.ExternalInquiryItem;
import com.apes.fn.scm.commodityInquiry.repository.ExternalInquiryItemRepository;
import com.apes.fn.crm.customerExpand.FnCustomerExpandRepository;
import com.apes.fn.server.pickUpCar.model.PickUpCar;
import com.apes.fn.server.pickUpCar.repository.PickUpCarRepository;
import com.apes.fn.server.pickUpCar.service.PickUpCarService;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.model.ServicePlanItem;
import com.apes.fn.server.servicePlan.repository.ServicePlanDao;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.tms.model.WaybillPlanningPlan;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.util.DistributedLock;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.car.model.CarConfiguration;
import com.apes.scm.masterdata.car.repository.CarConfigurationRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.party.model.AccessProvider;
import com.apes.scm.masterdata.product.model.Product;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务方案 与 定损方案 公共调用部分
 */
public abstract class AbstractPlan extends DomainService {

    private ServicePlanDao servicePlanDao;

    private ServicePlanRepository servicePlanRepository;

    private DistributedLock distributedLock;
    private ExternalInquiryItemRepository externalInquiryItemRepository;

    {
         servicePlanDao = SpringManager.getBean(ServicePlanDao.class);
         servicePlanRepository = SpringManager.getBean(ServicePlanRepository.class);
         distributedLock = SpringManager.getBean(DistributedLock.class);
        externalInquiryItemRepository = SpringManager.getBean(ExternalInquiryItemRepository.class);
    }
//    /**
//     * 插入实时数据(方案)
//     *
//     * @param servicePlan
//     * @return
//     */
//    public ServicePlan insertCommonData(ServicePlan servicePlan) {
//        ServicePlan nowOffice = getNowOffice(servicePlan);
//        JSONObject jsonObject = new JSONObject(MapUtil.mapped(nowOffice));
//        Boolean isInquiry = false;
//        try {
//            isInquiry = this.invoke("fn.servicePlan.checkInquiryGoods", MapUtil.mapper("conditionModel", jsonObject));
//        } catch (RuntimeException e) {
//            nowOffice.addErrorMsg(e.getMessage());
//        }
//        if (!isInquiry) nowOffice.setOrderTypeTemp("服务方案1");
//        return nowOffice;
//
//    }
//
//    /**
//     * 插入实时数据(定损)
//     * @param lossQuotation
//     * @return
//     */
//    public LossQuotation insertCommonData(LossQuotation lossQuotation){
//        LossQuotation nowOffice = getNowOffice(lossQuotation);
//        JSONObject jsonObject = new JSONObject(MapUtil.mapped(nowOffice));
//        Boolean isInquiry = this.invoke("fn.servicePlan.checkInquiryGoods", MapUtil.mapper("conditionModel", jsonObject));
//        if (!isInquiry)nowOffice.setOrderTypeTemp("定损报价单1");
//        return nowOffice;
//    }


    /**
     * 检验车辆信息
     * @param customerExpand
     */
    public  Map  checkCarInformation (FnCustomerExpand customerExpand) {
        //检验是否为国产车
        String code = customerExpand.getJekunModelCode();
        CarConfiguration carConfiguration = SpringManager.getBean(CarConfigurationRepository.class).findOne(code);
        Assert.isTrue(carConfiguration != null,"未找到配置车型信息, 会员扩展信息编码:"+customerExpand.getId());
        String str = carConfiguration.getYJFS();
        boolean b = carConfiguration.getCarModel() != null;
        String modelId = b?carConfiguration.getCarModel().getId():"";
        Map carPicture = new HashedMap();

        // 非合资 巴图鲁 需要车牌图片
        JSONObject param = new JSONObject();
        param.put("carLicense",customerExpand.getCarLicense());
        param.put("vendorCode",customerExpand.getVendorCode());
        Object obj = this.invoke("fn.customerCar.findOne", param);
        JSONObject resultJson = JSONObject.parseObject(obj.toString());

        JSONObject pic1 = resultJson.getJSONObject("pic1");
        JSONObject pic2 = resultJson.getJSONObject("pic2");
        JSONObject pic38 = resultJson.getJSONObject("pic38");
        if (!StringUtils.isEmpty(str) && "国产".equals(str)&&!modelId.equals("CYH0D")) {
            if (!resultJson.containsKey("pic1") || !resultJson.containsKey("pic38") || !resultJson.containsKey("pic2")) throw new RuntimeException("国产车请在APP上传车头,车尾,铭牌照!!!");
            judgePicture(pic1);
            judgePicture(pic2);
            judgePicture(pic38);
        }

        carPicture.putAll(MapUtil.mapper("headPicture", Objects.isNull(pic1)?"":pic1.get("path"), "trailPicture", Objects.isNull(pic2)?"":pic2.get("path"), "nameplatePicture", Objects.isNull(pic38)?"":pic38.get("path")));

        //判断车辆信息是否权
        judgeCarInfo(customerExpand,carConfiguration);
        return carPicture;
    }

    /**
     * 方案招解车
     * @param
     * @param customer
     * @param customerCar
     */
    public FnCustomerExpand findFnCustomerExpandAndSave(Dept dept,JSONObject customer,JSONObject customerCar) {

        FnCustomerExpand customerExpand =
                findValidServiceFnCustomerExpand(dept,customerCar.getString("carLicense"));
        // 重新更新数据
        customerExpand = this.invoke("fn.customerExpand.updateOrInsert",MapUtil.mapper(
                "customerExpand", customerExpand != null ? MapUtil.mapper("id", customerExpand.getId()) : null,
                "customerCar",customerCar,
                "customer",customer
                )
        );
        return customerExpand;

    }


    /**
     * 门店+车辆寻找有效的车辆拓展信息
     * @param dept
     * @param carlicense
     * @return
     */
    public FnCustomerExpand findValidServiceFnCustomerExpand(Dept dept,String carlicense){
        List<FnCustomerExpand> fnCustomerExpands = new ArrayList<>();
        fnCustomerExpands.addAll(findFnCustomerExpanByDeptAndCarLisence(carlicense,dept));
        fnCustomerExpands.addAll(SpringManager.getBean(PickUpCarService.class).findFnValidateCustomerExpandByDeptAndCarlicense(dept,carlicense));
        Map map = fnCustomerExpands.stream().collect(Collectors.groupingBy(FnCustomerExpand::getId));
        if(map.size() > 1){
//            throw new RuntimeException("该门店存在多份有效车辆拓扑信息，请检查");
            return refreshOrderFnCustomerExpand(dept, carlicense, fnCustomerExpands);
        }else if(map.size() == 1){
            return fnCustomerExpands.stream().findFirst().get();
        }else{
            return null;
        }
    }

    public void copyFnCustomerExpandToOrderSide(FnCustomerExpand fnCustomerExpand,Dept orderSideDept){
        AccessProvider accessProvider = orderSideDept.getCompany().queryAccessProvider();
        if (accessProvider==null)return;
        String carLicense = fnCustomerExpand.getCarLicense();
        List<FnCustomerExpand> orderSideExpand = SpringManager.getBean(FnCustomerExpandRepository.class).findAll(JpaDsl.toCriteriaIgnoreNull("vendorCode", "EQ", accessProvider.getId(), "carLicense", "EQ", carLicense));
        if (orderSideExpand.isEmpty()){
            FnCustomerExpand newExpand = new FnCustomerExpand();
            BeanUtils.copyProperties(fnCustomerExpand, newExpand,"vendorCode","id","pickUpTypeF");
            newExpand.setVendorCode(accessProvider.getId());
            newExpand.setVendorName(accessProvider.getName());
            SpringManager.getBean(FnCustomerExpandRepository.class).saveAndFlush(newExpand);
        }
    }

    private FnCustomerExpand refreshOrderFnCustomerExpand(Dept dept,String carlicense,List<FnCustomerExpand> fnCustomerExpandList){
        List conditionList = new ArrayList();
        conditionList.add("termination");
        conditionList.add("receivables");
        List<ServicePlan> servicePlans =
                servicePlanRepository.findServicePlanByFnCustomerExpandCarLicenseAndBelongDeptIdAndStateNotIn(carlicense,dept.getId(),conditionList);
        List<PickUpCar> pickUpCars =  SpringManager.getBean(PickUpCarRepository.class).findAll(JpaDsl.toCriteriaByEq("dept.id",dept.getId(),"fnCustomerExpand.carLicense",carlicense,"state","approve"));
        FnCustomerExpand fnCustomerExpand = fnCustomerExpandList.stream().max(Comparator.comparing(FnCustomerExpand::getCreateDate)).orElse(null);
        if (fnCustomerExpand==null)return fnCustomerExpand;
        servicePlans.stream().filter(servicePlan -> !servicePlan.getFnCustomerExpand().getId().equals(fnCustomerExpand.getId())).forEach(servicePlan -> {
            servicePlan.setFnCustomerExpand(fnCustomerExpand);
            servicePlanRepository.saveAndFlush(servicePlan);
        });
        pickUpCars.stream().filter(servicePlan -> !servicePlan.getFnCustomerExpand().getId().equals(fnCustomerExpand.getId())).forEach(pickUpCar -> {
            pickUpCar.setFnCustomerExpand(fnCustomerExpand);
            SpringManager.getBean(PickUpCarRepository.class).saveAndFlush(pickUpCar);
        });

        return fnCustomerExpand;
    }

    /**
     * 根据车牌，门店获取有效方案，返回车辆拓展信息
     * @param carLicense
     * @param dept
     * @return
     */
    public List<FnCustomerExpand> findFnCustomerExpanByDeptAndCarLisence(String carLicense,Dept dept){
        List conditionList = new ArrayList();
        conditionList.add("termination");
        conditionList.add("receivables");
        List<ServicePlan> servicePlans =
                servicePlanRepository.findServicePlanByFnCustomerExpandCarLicenseAndBelongDeptIdAndStateNotIn(carLicense,dept.getId(),conditionList);
        return servicePlans.stream().map(ServicePlan::getFnCustomerExpand).collect(Collectors.toCollection(ArrayList::new));
    }

    /**
     * 判断车辆信息
     * @param
     */
    private void judgeCarInfo (FnCustomerExpand customerExpand,CarConfiguration configuration) {
        if (configuration == null) throw new RuntimeException("该车辆信息不全,请检查车架号码，厂牌，车型，配置车型等信息！！！");
        if (StringUtils.isEmpty(customerExpand.getVin())) throw new RuntimeException("该车辆信息不全,请检查车架号码，厂牌，车型，配置车型等信息！！！");
        if (configuration.getCarLabel() == null) throw new RuntimeException("该车辆信息不全,请检查车架号码，厂牌，车型，配置车型等信息！！！");
        if (configuration.getCarModel() == null) throw new RuntimeException("该车辆信息不全,请检查车架号码，厂牌，车型，配置车型等信息！！！");

    }

    private void judgePicture (JSONObject carPicture) {
        if (!carPicture.containsKey("path") || StringUtils.isEmpty(carPicture.getString("path")))
            throw new RuntimeException("国产车请在APP上传车头,车尾,铭牌照!!!");
    }

    public Object insertCommonData(Object o){
        Object result = new Object();
        if (o instanceof ServicePlan){
            result = getNowOffice((ServicePlan) o);

        }else if (o instanceof LossQuotation){
            result = getNowOffice((LossQuotation) o);
        }else {
            throw new RuntimeException("未知方案");
        }
        return result;
    }


    /**
     * 插入方案明细报价信息
     *
     * @param servicePlan
     * @return
     */
    public ServicePlan getNowOffice(ServicePlan servicePlan) {
        List<ServicePlanItem> servicePlanItems = servicePlan.getServicePlanItems();
        JSONObject jsonService = new JSONObject(MapUtil.mapped(servicePlan,"servicePlanItems"));
        Boolean isInquiry = false;
        try {
            List inquiryPool = getInquiryPool(jsonService);
//            List inquiryPool = new ArrayList();
            servicePlanItems.forEach(servicePlanItem -> {
                // 拼装条件
                JSONObject tempJson = new JSONObject();
                tempJson.put("haveOffice", servicePlanItem.getHaveOffice());
                tempJson.put("uniqueValue", servicePlanItem.getUniqueValue());
                tempJson.put("vin", servicePlan.getFnCustomerExpand().getVin());
                JSONObject office = checkNowOffice(tempJson, servicePlanItem.getProduct(), servicePlan.getBelongDept(), inquiryPool, servicePlanItem.getPriceUnit(),servicePlanItem.isProductRule());
                servicePlanItem.setHaveOffice(office.getString("haveOffice"));
                servicePlanItem.setInquirySource(office.getString("inquirySource"));
            });
            //判断询价池是否有数据
            isInquiry = inquiryPool.size()>0;

        } catch (RuntimeException e) {
            e.printStackTrace();
            servicePlan.addErrorMsg(e.getMessage());
        }
        if (!isInquiry) servicePlan.setOrderTypeTemp("服务方案1");
        return servicePlan;
    }

    /**
     * 插入定损明细报价信息
     * @param lossQuotation
     * @return
     */
    public LossQuotation getNowOffice(LossQuotation lossQuotation){
        JSONObject jsonLoss = new JSONObject(MapUtil.mapped(lossQuotation, "lossQuotationRecords", "lossQuotationPlans", "lossQuotationItems"));
        try{
            List items = getInquiryPool(jsonLoss);
            lossQuotation.getLossQuotationItems().forEach(lossQuotationItem -> {
                // 拼装条件
                JSONObject tempJson = new JSONObject();
                tempJson.put("haveOffice", lossQuotationItem.getHaveOffice());
                tempJson.put("uniqueValue", lossQuotationItem.getUniqueValue());
                tempJson.put("vin",lossQuotation.getCustomerExpand().getVin());

                JSONObject office = checkNowOffice(tempJson, lossQuotationItem.getProduct(), lossQuotation.getFixedLossDept(), items, lossQuotationItem.getSaleQty(),lossQuotationItem.isProductRule());
                String haveOffice = office.getString("haveOffice");

                lossQuotationItem.setHaveOffice(haveOffice);
                lossQuotationItem.setInquirySource(office.getString("inquirySource"));
            });
            Boolean isInquiry =items.size()>0;
            if (!isInquiry)lossQuotation.setOrderTypeTemp("定损报价单1");
        } catch(Exception e) {
            e.printStackTrace();
            lossQuotation.addErrorMsg(e.getMessage());
        }
        return lossQuotation;
    }

    /**
     * 查询询价池商品(不包含保留期)
     *
     * @param conditionModel
     * @return List 询价池商品
     */
    public List getInquiryPool(JSONObject conditionModel) {
        Map inquiryPool = new HashMap();
        try {
            inquiryPool = this.invoke("commodityInquiry.order.getInquiryPool", conditionModel);
        } catch (Exception e) {
            e.printStackTrace();
            inquiryPool.put("item",new ArrayList<>());
        }
        return (List) inquiryPool.get("item");
    }

    /**
     * 查询是否有报价 (传入询价池)
     *
     * @param resultJson       返回结果集
     * @param product          商品
     * @param belongDept       做单门店
     * @param inquiryPoolItems 询价池商品
     * @param priceUnit        销售单价
     * @param productRule        是否带安
     * @return
     */
    public JSONObject checkNowOffice(JSONObject resultJson, Product product, Dept belongDept, List inquiryPoolItems, double priceUnit, boolean productRule) {
        resultJson.put("haveOffice", "暂无报价");
        resultJson.put("inquirySource", "none");
        JSONArray uniqueValueProducts = new JSONArray();
        //非带安工时直接返回
        if ("20".equals(product.getProductGroup().getId())&&!productRule){
            return resultJson;
        }
        if (!inquiryPoolItems.isEmpty()) {
            inquiryPoolItems.forEach(item -> {
                JSONObject itemJson = new JSONObject((Map) item);

                if (!itemJson.getJSONArray("item").isEmpty()) {
                    uniqueValueProducts.addAll(itemJson.getJSONArray("item"));
                }
                //如果原商品id一致,但'item'Key的value为空 说明无报价
                if (itemJson.getString("YSPID").equals(product.getId())) {
                    if (!itemJson.getJSONArray("item").isEmpty()) {
                        resultJson.put("YSPID", itemJson.getString("YSPID"));
                        resultJson.put("haveOffice", "已有报价");
                        resultJson.put("inquirySource", "sourceProduct");
                    }
                }
                uniqueValueProducts.forEach(v ->{
                    JSONObject items = new JSONObject((Map) v);
                    if (items.getString("SPID").equals(product.getId())){
                        resultJson.put("YSPID", itemJson.getString("YSPID"));
                        resultJson.put("haveOffice", "已有报价");
                        resultJson.put("inquirySource", "inquiry");
                    }
                });
            });
        }
        if (!resultJson.getString("haveOffice").equals("已有报价")) {
            //工时商品直接返回已有报价 TAPD 1046083 服务商品默认无报价
            /*if ("20".equals(product.getProductGroup().getId())) {
                resultJson.put("haveOffice", "已有报价");
            } else*/ /*if (resultJson.getString("uniqueValue") != null) {
                //已有唯一值直接返回已有报价
                resultJson.put("haveOffice", "已有报价");
            } else*/ if (priceUnit != 0 && "10".equals(product.getProductGroup().getId())) {
                //根据库存判断返回已有报价
                List storeForList = queryProductStoreForList(product, belongDept);
                if (storeForList.size() == 0) {
                    resultJson.put("haveOffice", "已有报价");
                    resultJson.put("inquirySource", "stock");
                }
            }
        }
        if (resultJson.containsKey("vin")&& "暂无报价".equals(resultJson.getString("haveOffice"))){
            List<ExternalInquiryItem> requireItems = externalInquiryItemRepository.findAll(
                    JpaDsl.toCriteria("externalInquiry.customerExpand.vin", "eq", resultJson.get("vin"), "externalInquiry.state", "eq", "approve", "validPeriod", "GTE", new Date(), "product.id", "eq", product.getId())
            );
            if (!requireItems.isEmpty()){
                resultJson.put("haveOffice", "已有报价");
                resultJson.put("inquirySource", "inquiry");
            }
        }
        return resultJson;
    }

    /**
     * 根据门店和商品信息查询库存
     *
     * @param product
     * @param belongDept
     * @return
     */
    public List queryProductStoreForList(Product product, Dept belongDept) {
        JSONObject param = new JSONObject();
        List productList = new ArrayList();
        List resultList = new ArrayList();
        JSONObject productId = new JSONObject();
        productId.put("productId", product.getId());
        productList.add(productId);
        param.put("NEW_DEPT_ID", belongDept.getId());
        param.put("OLD_DEPT_ID", belongDept.getOrigin());
        param.put("productList", productList);
        JSONArray array = servicePlanDao.queryProductStoreForList(param);

        resultList.addAll(array.stream().filter(tempJson -> {
            JSONObject item = (JSONObject) tempJson;
            return item.getDoubleValue("GENERAL_STOCK") + item.getDoubleValue("SUB_STOCK") + item.getDoubleValue("STOCK_AMOUNT") <= 0;
        }).collect(Collectors.toList()));
        return resultList;
    }

}
